﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using OpenQuarters.WebQuarters.Utils;
using System.Xml;
using System.Data.Linq;

namespace OpenQuarters.WebQuarters.Core
{
    public partial class CMSPageVersion : CMSEntity<CMSPageVersion, long>
    {
        [Newtonsoft.Json.JsonProperty]
        public long json_PageVersionId
        {
            get { return this.PageVersionId; }
            set { this.PageVersionId = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        public long json_PageId
        {
            get { return this.PageId; }
            set { this.PageId = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        public string json_Template
        {
            get { return this.Template; }
            set { this.Template = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        public string json_Title
        {
            get { return this.Title; }
            set { this.Title = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        public string json_Keywords
        {
            get { return this.Keywords; }
            set { this.Keywords = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        public string json_Description
        {
            get { return this.Description; }
            set { this.Description = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        public string json_Tags
        {
            get { return this.Tags; }
            set { this.Tags = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        public string json_UserId
        {
            get { return this.UserId; }
            set { this.UserId = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        public bool json_IsLive
        {
            get { return this.IsLive; }
            set { this.IsLive = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        public bool json_NoFollow
        {
            get { return this.NoFollow; }
            set { this.NoFollow = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        public int json_Order
        {
            get { return this.Order; }
            set { this.Order = value; }
        }

        [Newtonsoft.Json.JsonProperty]
        public string json_DateCreated
        {
            get { return this.DateCreated.ToString("U"); }
            set
            {
                try { this.DateCreated = DateTime.Parse(value); }
                catch { this.DateCreated = DateTime.UtcNow; }
            }
        }

        partial void OnTemplateChanging(string value)
        {
            if (String.IsNullOrEmpty(value))
            {
                string sError = "Template cannot be blank";
                throw new Exception(sError);
            }
        }

        public string[] GetTags()
        {
            if (string.IsNullOrEmpty(this.Tags))
                return new string[]{};
            else
                return this.Tags.Replace(" ,", "").Replace(", ", "").Replace("  ", " ").Split(',');
        }

        partial void OnCreated()
        {
            this.IsLive = false;
            this.DateCreated = DateTime.UtcNow;
            this.LanguageId = Language.Current.LanguageId;
            this.UserId = null;
            this.Title = "";
            this.Template = "Default";
        }

        private ContentDefinition contentDefinition = null;

        public ContentDefinition ContentDefinition
        {
            get
            {
                if (contentDefinition == null)
                {
                    contentDefinition = ContentDefinition.FromJSON(this.Definition);
                }
                return contentDefinition;
            }
            set
            {
                contentDefinition = value;
            }
        }

        public override void OnSaving()
        {
            base.OnSaving();
            this.Definition = this.ContentDefinition.ToJSON();
        }

        public override void OnSaved()
        {
            base.OnSaved();
            if (this.Title != null && this.Title.Length > 0 && Url.Table.FirstOrDefault(e => e.PageId == this.PageId && e.LanguageId == this.LanguageId) == null)
            {
                Url url = new Url()
                {
                    PageId = this.PageId,
                    LanguageId = this.LanguageId,
                    PageUrl = this.GenerateUrl()
                }.Save();
            }
        }

        public string GenerateUrl()
        {
            string url = "";
            var p = this;
            url = p.Title.ToUrlSafeString();
            while (p != null)
            {
                p = p.CMSPage.ParentId == null ? null : p.CMSPage.ParentPage.CurrentVersion;
                if (p != null && p.Title != null && p.Title.Length > 0 && p.CMSPage.ParentId != null)
                {
                    url = p.Title.ToUrlSafeString() + "/" + url;
                }
            }
            return url;
        }

        public override System.Linq.Expressions.Expression<Func<CMSPageVersion, bool>> GetIDSelector(long ID)
        {
            return e => e.PageVersionId == ID;
        }

        public override long GetKey(CMSPageVersion Entity)
        {
            return Entity.PageVersionId;
        }

        public override DataLoadOptions GetLoadOptions()
        {
            var r = new DataLoadOptions();
            r.LoadWith<CMSPageVersion>(e => e.CMSPage);
            return r;
        }

        public class JSON
        {
            public CMSPageVersion PageVersion = null;
            public string Definition = "{}";

            public JSON(CMSPageVersion PageVersion)
            {
                this.PageVersion = PageVersion;
                this.Definition = PageVersion.Definition;
            }

            public JSON()
            {
            }
        }

        public void MakeLive()
        {
            Table.Where(e => e.IsLive && e.PageId == this.PageId).ToList().ForEach(e => e.Delete());

            var v = CMSPageVersion.Load(this.PageVersionId);

            v.IsLive = true;
            v.UserId = null;
            v = v.Save();

            EventLog.Add(EventLogPriority.L, "CMSPageVersion.MakeLive", this.PageId.ToString(), new CMSPageVersion.JSON(v).ToJSON());
        }

        //public static List<CMSPageVersion> GetVersionsForUser(long PageId)
        //{
        //    var versions = CMSPageVersion.Table
        //        .Where(v => v.PageId == PageId && v.IsLive == false)
        //    return versions.OrderByDescending(v => v.DateCreated).ToList();
        //}

        public static List<CMSPageVersion> GetVersionsForUser(long PageId)
        {
            var versions = new List<CMSPageVersion>();
            var events = EventLog.Table
                .Where(e => e.Category == "CMSPageVersion.MakeLive" && e.Target == PageId.ToString())
                .ToList();
            foreach (var evt in events)
            {
                var pageJSON = GeneralUtils.FromJSON<CMSPageVersion.JSON>(evt.Message);
                pageJSON.PageVersion.Definition = pageJSON.Definition;
                versions.Add(pageJSON.PageVersion);
            }
            return versions.OrderByDescending(e => e.DateCreated).ToList();
        }

        public static CMSPageVersion GetVersionsFromArchive(long PageId, long PageVersionId)
        {
            var versions = new List<CMSPageVersion>();
            var events = EventLog.Table
                .Where(e => e.Category == "CMSPageVersion.MakeLive" && e.Target == PageId.ToString())
                .ToList();
            foreach (var evt in events)
            {
                var pageJSON = GeneralUtils.FromJSON<CMSPageVersion.JSON>(evt.Message);
                pageJSON.PageVersion.Definition = pageJSON.Definition;
                if (pageJSON.PageVersion.PageVersionId == PageVersionId)
                    return pageJSON.PageVersion;
            }
            return null;
        }
    }
}
